package pe.com.casadesign.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

import pe.com.casadesign.dao.DiseniadorDAO;
import pe.com.casadesign.domain.Diseniador;
import pe.com.casadesign.domain.ListaDiseniador;

/**
 * Implementacion de DiseniadorDAO.
 * 
 * @author Pedro Vera
 * 
 */
@Repository
public class DiseniadorDAOImpl implements DiseniadorDAO {
	private static final Logger logger = LoggerFactory.getLogger(DiseniadorDAOImpl.class);
	
	// Nombre Procedimientos Almacenados
	private static String SP_LISTAR_DISENIADOR = "SP_LISTAR_DISENIADOR";
	private static String SP_OBTENER_DISENIADOR = "SP_OBTENER_DISENIADOR";
	private static String SP_REGISTRAR_DISENIADOR = "SP_REGISTRAR_DISENIADOR";
	private static String SP_MODIFICAR_DISENIADOR = "SP_MODIFICAR_DISENIADOR";
	private static String SP_ELIMINAR_DISENIADOR = "SP_ELIMINAR_DISENIADOR";
		
	// Parametros de Entrada
	private static String PARAM_CODDISENIADOR = "p_coddiseniador";
	private static String PARAM_NOMBRESYAPELLIDOS = "p_nombresyapellidos";
	private static String PARAM_DIRECCION = "p_direccion";
	private static String PARAM_EMAIL = "p_email";
	private static String PARAM_TELEFONO = "p_telefono";
	private static String PARAM_ESTADO = "p_estado";
	
	// Parametros de Salida
	private static String CODDISENIADOR = "CODDISENIADOR";
	private static String NOMBRESYAPELLIDOS = "NOMBRESYAPELLIDOS";
	private static String DIRECCION = "DIRECCION";
	private static String EMAIL = "EMAIL";
	private static String TELEFONO = "TELEFONO";
	private static String ESTADO = "ESTADO";
	private static String FECHAREGISTRO = "FECHAREGISTRO";
	
	private static String LISTADO = "LISTADO";
	
	private static String TOTAL_FILAS_AFECTADAS = "#update-count-1";
	
	private JdbcTemplate jdbcTemplate;

	@Autowired
    public void setDataSource(DataSource dataSource)
    {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
	
	@Override
	public ListaDiseniador listarDiseniador(Diseniador diseniador) {
		logger.info("listarDiseniador");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LISTAR_DISENIADOR).
	    						  returningResultSet(LISTADO, new RowMapper<Diseniador>(){
									@Override
									public Diseniador mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Diseniador diseniador = new Diseniador();
								        diseniador.setCodDiseniador(rs.getInt(CODDISENIADOR));
								        diseniador.setNombresyApellidos(rs.getString(NOMBRESYAPELLIDOS));
								        diseniador.setDireccion(rs.getString(DIRECCION));
								        diseniador.setEmail(rs.getString(EMAIL));
								        diseniador.setTelefono(rs.getString(TELEFONO));
								        diseniador.setEstado(rs.getString(ESTADO));
								        diseniador.setFechaRegistro(rs.getDate(FECHAREGISTRO).toString());
								        return diseniador;
								    }
	    						  }
								);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_NOMBRESYAPELLIDOS, diseniador.getNombresyApellidos())
	    								.addValue(PARAM_ESTADO, diseniador.getEstado()); 

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Diseniador> listaDiseniador= (List<Diseniador>)data.get(LISTADO);
        
		// Instanciando objeto ListaDiseniador
		ListaDiseniador listaDiseniadorResultado = new ListaDiseniador();
        // Estableciendo resultado al objeto listaDiseniadorResultado
		listaDiseniadorResultado.setLista(listaDiseniador);
        
        if (logger.isDebugEnabled() && listaDiseniadorResultado != null)
        {
            logger.debug("size=" + listaDiseniadorResultado.size());
        }
        return listaDiseniadorResultado;
	}

	@Override
	public Diseniador obtenerDiseniador(Diseniador diseniador) {
		logger.info("obtenerDiseniador");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_OBTENER_DISENIADOR).
								  returningResultSet(LISTADO, new RowMapper<Diseniador>(){
								  @Override
									public Diseniador mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Diseniador diseniador = new Diseniador();
								        diseniador.setCodDiseniador(rs.getInt(CODDISENIADOR));
								        diseniador.setNombresyApellidos(rs.getString(NOMBRESYAPELLIDOS));
								        diseniador.setDireccion(rs.getString(DIRECCION));
								        diseniador.setEmail(rs.getString(EMAIL));
								        diseniador.setTelefono(rs.getString(TELEFONO));
								        diseniador.setEstado(rs.getString(ESTADO));
								        diseniador.setFechaRegistro(rs.getDate(FECHAREGISTRO).toString());
								        return diseniador;
								    }
								  }
								);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODDISENIADOR, diseniador.getCodDiseniador());

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Diseniador> listaDiseniador= (List<Diseniador>)data.get(LISTADO);
        
		// Declarando objeto Diseniador Obtenido
		Diseniador diseniadorObtenido = null;
		
		if (listaDiseniador != null && listaDiseniador.size()>0){
			// Obteniendo el primer elemento de la lista de diseniador
			diseniadorObtenido = listaDiseniador.get(0);
		}
        
        if (logger.isDebugEnabled() && listaDiseniador != null)
        {
            logger.debug("size=" + listaDiseniador.size());
        }
        
		return diseniadorObtenido;
	}

	@Override
	public boolean registrarDiseniador(Diseniador diseniador) {
		logger.info("registrarDiseniador");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_DISENIADOR);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_NOMBRESYAPELLIDOS, diseniador.getNombresyApellidos())
	    								.addValue(PARAM_DIRECCION , diseniador.getDireccion())
	    								.addValue(PARAM_EMAIL, diseniador.getEmail())
	    								.addValue(PARAM_TELEFONO, diseniador.getTelefono())
	    								.addValue(PARAM_ESTADO, diseniador.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    return totalRegistrosAfectado > 0;
	}

	@Override
	public boolean modificarDiseniador(Diseniador diseniador) {
		logger.info("modificarDiseniador");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_MODIFICAR_DISENIADOR);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODDISENIADOR, diseniador.getCodDiseniador())
	    								.addValue(PARAM_NOMBRESYAPELLIDOS, diseniador.getNombresyApellidos())
	    								.addValue(PARAM_DIRECCION , diseniador.getDireccion())
	    								.addValue(PARAM_EMAIL, diseniador.getEmail())
	    								.addValue(PARAM_TELEFONO, diseniador.getTelefono())
	    								.addValue(PARAM_ESTADO, diseniador.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    return totalRegistrosAfectado > 0;
	}

	@Override
	public boolean eliminarDiseniador(Diseniador diseniador) {
		logger.info("eliminarDiseniador");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_ELIMINAR_DISENIADOR);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODDISENIADOR, diseniador.getCodDiseniador());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    return totalRegistrosAfectado > 0;
	}

}
